package cn.com.generaldata.os.service.indicator_evaluation.industry_spread_effect;

import java.util.List;

import org.apache.commons.lang3.Validate;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.sql.Criteria;
import org.nutz.lang.random.R;

import cn.com.generaldata.jsme_indicator_system.entity.Dustry;
import cn.com.generaldata.jsme_indicator_system.entity.IndicatorConsumptResult;
import cn.com.generaldata.jsme_indicator_system.entity.IndicatorEvaluation;
import cn.com.generaldata.os.service.impl.DustryService;
import cn.com.generaldata.os.service.impl.IndicatorConsumptService;
import cn.com.generaldata.os.service.indicator_evaluation.CalculateService;
import cn.com.generaldata.os.service.indicator_evaluation.CalculateServiceHelper;
import cn.com.generaldata.os.util.SpringContextHolder;
import cn.com.generaldata.os.vo.IndicatorAccountVO;

/**
 * 产业波及效果系数指标计算类.
 */
public class IndustrySpreadEffectCoefficientCalculateService implements CalculateService {

	private Dao dao;

	private Dao indicatorSystemDao;

	private CalculateServiceHelper helper;

	private String subTypeName = "波及效果系数";

	@Override
	public void calculateIndicator(IndicatorEvaluation indicator, IndicatorAccountVO indicatorAccountVO) {
		DustryService dustryService = SpringContextHolder.getBean(DustryService.class);
		IndicatorConsumptService indicatorConsumptService = SpringContextHolder.getBean(IndicatorConsumptService.class);

		Validate.isTrue(indicatorConsumptService.checkHasData(indicatorAccountVO.getYear()), "不存在该年份直接消耗系数数据");

		List<Dustry> dustries = dustryService.getEnableDustrys(indicatorAccountVO.getYear());

		for (Dustry dustry : dustries) {
			Double result = calculateResult(indicatorAccountVO.getYear(), dustry);
			saveResult(indicatorAccountVO.getYear(), dustry, result);
		}
	}

	/**
	 * 计算结果
	 * 
	 * @param year 年份
	 * @param dustry 国民经济代码.
	 * @return
	 */
	private Double calculateResult(int year, Dustry dustry) {
		Criteria sensitivityCri = getIndicatorDataCri(year, "感应度系数", dustry);
		IndicatorConsumptResult sensitivity = dao.fetch(IndicatorConsumptResult.class, sensitivityCri);
		Validate.isTrue(sensitivity != null);

		Criteria influenceCri = getIndicatorDataCri(year, "影响力系数", dustry);
		IndicatorConsumptResult influence = dao.fetch(IndicatorConsumptResult.class, influenceCri);
		Validate.isTrue(influence != null);

		return (sensitivity.getIndicatorValue() + influence.getIndicatorValue()) / 2;
	}

	/**
	 * 保存指标结果.
	 * 
	 * @param indicatorAccountVO
	 * @param result
	 */
	private void saveResult(int year, Dustry dustry, Double result) {
		Criteria cri = getIndicatorDataCri(year, subTypeName, dustry);
		IndicatorConsumptResult record = dao.fetch(IndicatorConsumptResult.class, cri);
		if (record != null) {
			dao.clear(IndicatorConsumptResult.class, cri);
		}

		IndicatorConsumptResult icr = new IndicatorConsumptResult();
		icr.setId(R.UU64());
		icr.setYear(year);
		icr.setTypeName("影响系数");
		icr.setSubTypeName(subTypeName);
		icr.setDustryId(dustry.getId());
		icr.setIndicatorValue(Double.valueOf(String.format("%.10f", result)));

		dao.insert(icr);
	}

	private Criteria getIndicatorDataCri(int year, String subType, Dustry dustry) {
		Criteria cri = Cnd.cri();
		cri.where().and("year", "=", year);
		cri.where().and("subTypeName", "=", subType);
		cri.where().and("dustryId", "=", dustry.getId());
		return cri;
	}

	@Override
	public void setDao(Dao dao) {
		this.dao = dao;
	}

	@Override
	public void setIndicatorSystemDao(Dao indicatorSystemDao) {
		this.indicatorSystemDao = indicatorSystemDao;
	}

	@Override
	public void setCalculateServiceHelper(CalculateServiceHelper calculateServiceHelper) {
		helper = calculateServiceHelper;
	}

}
